package com.xique.park.service.biz.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xique.common.core.constant.Constants;
import com.xique.common.core.domain.R;
import com.xique.common.core.utils.SecurityUtils;
import com.xique.common.core.utils.StringUtils;
import com.xique.common.core.web.domain.AjaxResult;
import com.xique.park.bean.domain.ParkCar;
import com.xique.park.bean.domain.ParkConfig;
import com.xique.park.bean.domain.ParkInfo;
import com.xique.park.bean.domain.ParkPayPp;
import com.xique.park.bean.request.web.parkInfo.ParkBaseInfoSaveRequest;
import com.xique.park.bean.request.web.parkInfo.ParkParamConfigSaveRequest;
import com.xique.park.bean.request.web.parkInfo.ParkPayConfigSaveRequest;
import com.xique.park.bean.transform.web.ParkDetailInfoTransform;
import com.xique.park.bean.vo.web.parkinfo.ParkBaseInfoVo;
import com.xique.park.bean.vo.web.parkinfo.ParkParamConfigVo;
import com.xique.park.bean.vo.web.parkinfo.ParkPayConfigVo;
import com.xique.park.enums.PayChannelEnum;
import com.xique.park.service.biz.service.IParkDetailInfoBizService;
import com.xique.park.service.command.service.IParkConfigCommandService;
import com.xique.park.service.service.IParkCarService;
import com.xique.park.service.service.IParkConfigService;
import com.xique.park.service.service.IParkInfoService;
import com.xique.park.service.service.IParkPayPpService;
import com.xique.system.api.RemoteSystemProjectService;
import com.xique.system.api.dto.SystemProjectDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 车场信息 service
 *
 * @author: xique
 */
@Service
@Slf4j
public class ParkDetailInfoBizServiceImpl implements IParkDetailInfoBizService {

    @Value("${park.icbc.onParkUrl}")
    private String onParkUrl;

    @Resource
    private RemoteSystemProjectService remoteSystemProjectService;

    @Autowired
    private IParkConfigService parkConfigService;

    @Autowired
    private IParkPayPpService parkPayPpService;

    @Autowired
    private IParkConfigCommandService parkConfigCommandService;

    @Autowired
    private IParkInfoService parkInfoService;

    @Autowired
    private IParkCarService parkCarService;

    @Override
    public AjaxResult getParkBaseInfo() {
        Long parkId = SecurityUtils.getParkId();
        if (null == parkId) {
            return AjaxResult.error("车场ID不能为空");
        }
        // 项目参数
        R<SystemProjectDTO> res = remoteSystemProjectService.getProjectInfo(parkId);
        SystemProjectDTO systemProjectDTO = res.getData();
        // 车场配置参数
        ParkConfig parkConfig = new ParkConfig();
        parkConfig.setParkId(parkId);
        List<ParkConfig> configList = parkConfigService.selectParkConfigList(parkConfig);
        ParkConfig config = !configList.isEmpty() ? configList.get(0) : null;
        ParkBaseInfoVo parkBaseInfoVo = ParkDetailInfoTransform.transformParkBaseInfoVo(systemProjectDTO, config);
        return AjaxResult.success(parkBaseInfoVo);
    }

    @Override
    public AjaxResult saveBaseInfo(ParkBaseInfoSaveRequest request) {
        int count;
        Long parkId = SecurityUtils.getParkId();
        ParkConfig parkConfig = parkConfigService.selectParkConfigByParkId(parkId);
        if (null != parkConfig) {
            ParkConfig parkConfigNew = ParkDetailInfoTransform.transformBaseInfoSaveRequest(request);
            parkConfigNew.setId(parkConfig.getId());
            count = parkConfigService.updateParkConfig(parkConfigNew);
        } else {
            count = parkConfigService.insertParkConfig(ParkDetailInfoTransform.transformBaseInfoSaveRequest(request));
        }
        ParkInfo parkInfo = new ParkInfo();
        parkInfo.setId(SecurityUtils.getParkId());
        parkInfo.setAddress(request.getAddress());
        parkInfo.setCity(request.getCity());
        parkInfo.setProvince(request.getProvince());
        parkInfo.setDistrict(request.getDistrict());
        parkInfo.setIsOpenPark(request.getIsOpenPark());
        parkInfo.setFeeRule(request.getFeeRule());
        parkInfoService.updateById(parkInfo);
        if (count > 0) {
            return AjaxResult.success("保存成功");
        } else {
            return AjaxResult.error("保存失败");
        }
    }

    @Override
    public AjaxResult getParamConfig() {
        Long parkId = SecurityUtils.getParkId();
        if (null == parkId) {
            return AjaxResult.error("车场ID不能为空");
        }
        // 车场配置参数
        ParkConfig parkConfig = new ParkConfig();
        parkConfig.setParkId(parkId);
        List<ParkConfig> configList = parkConfigService.selectParkConfigList(parkConfig);
        ParkConfig config = !configList.isEmpty() ? configList.get(0) : null;
        ParkParamConfigVo vo = ParkDetailInfoTransform.transformParkParamConfigVo(config);
        return AjaxResult.success(vo);
    }

    @Override
    public AjaxResult saveParkConfigInfo(ParkParamConfigSaveRequest request) {
        int count;
        ParkConfig parkConfig;
        boolean checkResult = false;
        Long parkId = SecurityUtils.getParkId();
        ParkConfig oldParkConfig = parkConfigService.selectParkConfigByParkId(parkId);
        if (null != oldParkConfig) {
            checkResult = checkEnGarageSpaces(request);
            parkConfig = ParkDetailInfoTransform.transformParamConfigSaveRequest(request);
            count = parkConfigService.updateParkConfig(parkConfig);
        } else {
            parkConfig = ParkDetailInfoTransform.transformParamConfigSaveRequest(request);
            count = parkConfigService.insertParkConfig(parkConfig);
        }
        if (count > 0) {
            if (checkResult) {
                return parkConfigCommandService.downParkConfig(parkConfig, "保存成功！车场下存在分车库统计车位得车辆，是否启用分车库统计车位不可更改！");
            } else {
                return parkConfigCommandService.downParkConfig(parkConfig, "保存成功！");
            }
        } else {
            return AjaxResult.error("保存失败");
        }
    }

    /**
     * 判断车场下的车辆是否有开启分车库统计车位
     */
    private boolean checkEnGarageSpaces(ParkParamConfigSaveRequest request) {
        AtomicBoolean checkEnGarageSpaces = new AtomicBoolean(false);

        ParkConfig parkConfigInDb = parkConfigService.selectParkConfigById(request.getId());
        if (null != parkConfigInDb) {
            String jsonConfig = parkConfigInDb.getConfig();
            JSONObject configJsonObj = (JSONObject) JSON.parse(jsonConfig);
            if (null != configJsonObj) {
                String oldEnGarageSpaces = configJsonObj.getString("enGarageSpaces");
                String newEnGarageSpaces = request.getEnGarageSpaces();
                // 是改成否，需要判断车场下的车辆是否有开启分车库统计车位的，如果有的话，就不能更改；否改成是无需判断，都是可以更改
                if (Constants.YES.equals(oldEnGarageSpaces) && Constants.NO.equals(newEnGarageSpaces)) {
                    ParkCar search = new ParkCar();
                    search.setParkId(SecurityUtils.getParkId());
                    List<ParkCar> parkCarList = parkCarService.selectParkCarList(search);

                    if (parkCarList.isEmpty()) {
                        // 判断车场下的车辆是否有开启分车库统计车位，默认为没有
                        parkCarList.forEach(parkCar -> {
                            String carEnGarageSpaces = parkCar.getIsGarageSpace();
                            if (Constants.YES.equals(carEnGarageSpaces)) {
                                checkEnGarageSpaces.set(true);
                            }
                        });
                        if (checkEnGarageSpaces.get()) {
                            // 有车辆开启分车库统计车位，不可以更改，则用原先得旧值
                            request.setEnGarageSpaces(oldEnGarageSpaces);
                        }
                    }
                }
            }
        }
        return checkEnGarageSpaces.get();
    }

    /**
     * 获取支付配置
     * 备注：目前先获取PP的，后续对接其他支付以后，此模块再修改
     */
    @Override
    public AjaxResult getPayConfig(Long parkId) {
        if (parkId == null){
            parkId = SecurityUtils.getParkId();
        }
        if (null == parkId) {
            return AjaxResult.error("车场ID不能为空");
        }
        ParkPayPp parkPayPp = new ParkPayPp();
        parkPayPp.setParkId(parkId);
        parkPayPp.setStatus("normal");
        List<ParkPayPp> list = parkPayPpService.selectParkPayPpList(parkPayPp);
        if (CollectionUtils.isEmpty(list)) {
            return AjaxResult.success("车场电子支付未配置");
        } else {
            if (list.size() == 1) {
                ParkPayConfigVo parkPayConfigVo = ParkDetailInfoTransform.transformParkPayConfigVo(list.get(0));
                return AjaxResult.success(parkPayConfigVo);
            } else {
                return AjaxResult.error("该车场存在多个电子支付配置，请联系管理人员");
            }
        }
    }

    /**
     * 保存支付配置
     * 备注：目前只支持PP
     */
    @Override
    public AjaxResult savePayConfig(ParkPayConfigSaveRequest request) {
        Long parkId = request.getParkId();
        if (parkId == null){
            parkId = SecurityUtils.getParkId();
        }
        if (parkId == null){
            return AjaxResult.error("车场ID不能为空");
        }
        ParkInfo parkInfo1 = parkInfoService.selectParkInfoById(parkId);
        parkInfo1.setPayChannel(request.getPayChannel());
        parkInfoService.updateById(parkInfo1);
        int count;
        ParkPayPp parkPayPp = new ParkPayPp();
        parkPayPp.setStatus(request.getStatus());
        parkPayPp.setParkId(request.getParkId());
        parkPayPp.setId(request.getId());
        parkPayPp.setServerUrl(request.getServerUrl());
        parkPayPp.setServerPort(request.getServerPort());
        parkPayPp.setParkUuid(request.getParkUuid());
        parkPayPp.setAppSecret(request.getAppSecret());

        ParkPayPp parkPay = new ParkPayPp();
        parkPay.setParkUuid(request.getParkUuid());
        List<ParkPayPp> list = parkPayPpService.selectParkPayPpList(parkPay);
        // 新增
        if (null != parkPayPp.getId()) {

            if (!CollectionUtils.isEmpty(list) && list.get(0).getId().equals(request.getId()) || CollectionUtils.isEmpty(list)) {
                // 更新
                count = parkPayPpService.updateParkPayPp(parkPayPp);
            } else {
                count = -1;
            }
        } else {

            if (CollectionUtils.isEmpty(list)) {
                count = parkPayPpService.insertParkPayPp(parkPayPp);
            } else {
                count = -1;
            }
        }
        if (count > 0) {
            return AjaxResult.success("保存成功");
        } else if (count < 0) {
            ParkInfo parkInfo = parkInfoService.selectParkInfoById(list.get(0).getParkId());
            return AjaxResult.error("停车场UUID已存在【" + parkInfo.getName() + "】车场，请重新填写");
        } else {
            return AjaxResult.error("保存失败");
        }
    }

    @Override
    public AjaxResult getPrePayUrl() {
        Long parkId = SecurityUtils.getParkId();
        if (null == parkId) {
            return AjaxResult.error("车场ID不能为空");
        }
        ParkPayPp parkPayPp = new ParkPayPp();
        parkPayPp.setParkId(parkId);
        List<ParkPayPp> list = parkPayPpService.selectParkPayPpList(parkPayPp);
        if (list.isEmpty()) {
            return AjaxResult.error("车场支付参数未配置");
        }
        if (list.size() > 1) {
            return AjaxResult.error("该车场存在多个电子支付配置，请联系管理人员");
        }
        String parkUuid = list.get(0).getParkUuid();
        if (StringUtils.isEmpty(parkUuid)) {
            return AjaxResult.error("UUID不能为空");
        }
        Map<String, Object> map = new HashMap<>(1);
        // 轻纺城面临采购中心
        if (parkId == 590) {
            map.put("url", "https://qrx.4pyun.com/parking?req=plate&park_uuid=" + parkUuid);
        } else {
            map.put("url", "https://qr.4pyun.com/parking?req=plate&park_uuid=" + parkUuid);
        }
        return AjaxResult.success(map);
    }

    @Override
    public AjaxResult getPrePayUrlV1() {
        Long parkId = SecurityUtils.getParkId();
        if (null == parkId) {
            return AjaxResult.error("车场ID不能为空");
        }
        ParkInfo info = parkInfoService.selectParkInfoById(parkId);
        if (info == null) {
            return AjaxResult.error("未找到对应的车场信息");
        }
        Map<String, Object> map = new HashMap<>(1);

        if (PayChannelEnum.ICBC.getChannel().equals(info.getPayChannel())) {
            map.put("url", "https://inpark.xiquepark.net?parkId=" + parkId + "&tabBar=true");
            return AjaxResult.success(map);
        } else if (PayChannelEnum.PP.getChannel().equals(info.getPayChannel())) {
            ParkPayPp parkPayPp = new ParkPayPp();
            parkPayPp.setParkId(parkId);
            List<ParkPayPp> list = parkPayPpService.selectParkPayPpList(parkPayPp);
            if (list.isEmpty()) {
                return AjaxResult.error("车场支付参数未配置");
            }
            if (list.size() > 1) {
                return AjaxResult.error("该车场存在多个电子支付配置，请联系管理人员");
            }
            String parkUuid = list.get(0).getParkUuid();
            if (StringUtils.isEmpty(parkUuid)) {
                return AjaxResult.error("UUID不能为空");
            }
            // 轻纺城面临采购中心
            if (590 == parkId) {
                map.put("url", "https://qrx.4pyun.com/parking?req=plate&park_uuid=" + parkUuid);
            } else {
                map.put("url", "https://qr.4pyun.com/parking?req=plate&park_uuid=" + parkUuid);
            }
        }
        return AjaxResult.success(map);
    }
}
